﻿using System;
using System.Linq;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using BrainTechLLC;
using ImageAppDataModels;
using ImageAppViewModels;

namespace FullViewer.Plugin
{
    /// <summary>
    /// Interaction logic for FullImageView.xaml
    /// </summary>
    public partial class FullImageView : UserControl
    {
        public event EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>> RequestDelete;
        public event EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>> RequestResizeDelete;
        public event EventHandler<ObjectEventArgsNonRef<FileImageViewModel, bool>> RequestResize;
        public event EventHandler<ObjectEventArgsNonRef<RotationParams, bool>> RequestRotate;

        private double _originalSizeX = 0D;
        private double _originalSizeY = 0D;
        internal static double ZoomFactor = 0.2D;
        public FullViewerWindow FullViewerWindow;
        protected DispatcherTimer _dt;
        protected FileImageViewModel _vm;

        public static readonly DependencyProperty FileImageViewModelProperty =
            DependencyProperty.Register("FileImageViewModel", typeof(FileImageViewModel), typeof(FullImageView), new PropertyMetadata(null, OnFileImageViewModelPropertyChanged));

        public FileImageViewModel FileImageViewModel
        {
            get { return (FileImageViewModel)GetValue(FileImageViewModelProperty); }
            set { _vm = value; SetValue(FileImageViewModelProperty, value); }
        }

        private static void OnFileImageViewModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FullImageView source = d as FullImageView;
            source.UpdateFileImageViewModel(e.NewValue as FileImageViewModel, e.OldValue as FileImageViewModel);
        }

        private void UpdateFileImageViewModel(FileImageViewModel viewModel, FileImageViewModel viewModelOld)
        {
            if (viewModelOld != null)
            {
                viewModelOld.PropertyChanged -= viewModel_PropertyChanged;
            }

            if (viewModel != null)
            {
                if (_dt == null)
                {
                    _dt = new DispatcherTimer(DispatcherPriority.Input);
                    _dt.Interval = new TimeSpan(0, 0, 0, 0, 50);
                    _dt.Tick += new EventHandler(dt_Tick);
                }

                viewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(viewModel_PropertyChanged);
                FileImageViewModel = viewModel;
                viewModel.SetCurrentWidthHeight(this.ActualWidth, this.ActualHeight);

                if (viewModel.Item.ImageSourceCached != null)
                {
                    imageInfo.UpdateFileImageViewModel(viewModel, viewModelOld);
                    imageInfo.DataContext = viewModel;
                    imgMain.FileImageViewModel = viewModel;
                    commandBar.FileImageViewModel = viewModel;
                }
                else
                {
                    imageInfo.FileImageViewModel = null;

                    var fi = viewModel.FileImage as FileImage;
                    LazyLoadingImageSource._lazyLoaderImageSource.SetTopPriority(fi);

                    if (!fi._lazyLoadingImageSource)
                    {
                        viewModel.GetImageSource();
                    }

                    _dt.Start();
                }
            }
            else
            {
                imgMain.FileImageViewModel = null;
                imgMain.ImageSource = null;
                imgMain.DataContext = null;
            }
        }

        void viewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ViewerIsTopmost" && FullViewerWindow != null)
            {
                FullViewerWindow.Topmost = Settings.Values.ViewerIsTopmost;
            }
            else if (e.PropertyName == "Bitmap")
            {
                Dispatcher.BeginInvoke(new VoidDelegate(() => UpdateFileImageViewModel(sender as FileImageViewModel, _vm)));
            }
        }

        public void DoneWithBlurCalc()
        {
        }

        private void dt_Tick(object sender, EventArgs e)
        {
            if (FileImageViewModel != null)
            {
                FileImageViewModel vm = FileImageViewModel;

                if (vm.Item.ImageSourceCached != null)
                {
                    if (_dt != null)
                    {
                        _dt.Stop();
                    }
                    imageInfo.UpdateFileImageViewModel(vm, null);
                    imageInfo.DataContext = vm;
                    imgMain.FileImageViewModel = vm;
                    commandBar.FileImageViewModel = vm;
                    Debug.WriteLine("Image source loaded and full image view model set for " + vm.FileNameOnly);
                    return;
                }
            }
            else
            {
                if (_dt != null)
                {
                    _dt.Stop();
                }
            }
        }

        public FullImageView()
        {
            InitializeComponent();
            SizeChanged += new SizeChangedEventHandler(FullImageView_SizeChanged);
        }

        void FullImageView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (FileImageViewModel != null && this.ActualWidth > 0 && this.ActualHeight > 0)
            {
                FileImageViewModel.SetCurrentWidthHeight(this.ActualWidth, this.ActualHeight);
            }
        }

        internal void Zoom()
        {
            if (_originalSizeX == 0)
            {
                _originalSizeX = imgMain.ActualWidth;
                _originalSizeY = imgMain.ActualHeight;
            }
            double xIncrease = (_originalSizeX * ZoomFactor);
            double yIncrease = (_originalSizeY * ZoomFactor);

            imgMain.Width = imgMain.ActualWidth + xIncrease;
            imgMain.Height = imgMain.ActualHeight + yIncrease;

            if (imgMain.Width > scroller.ActualWidth)
            {
                scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + (xIncrease / 2D));
            }

            if (imgMain.Height > scroller.ActualHeight)
            {
                scroller.ScrollToVerticalOffset(scroller.VerticalOffset + (yIncrease / 2D));
            }
        }

        internal void Shrink()
        {
            if (_originalSizeX == 0)
            {
                _originalSizeX = imgMain.ActualWidth;
                _originalSizeY = imgMain.ActualHeight;
            }
            double xIncrease = (_originalSizeX * ZoomFactor);
            double yIncrease = (_originalSizeY * ZoomFactor);

            imgMain.Width = Math.Max(imgMain.ActualWidth - xIncrease, 32);
            imgMain.Height = Math.Max(imgMain.ActualHeight - yIncrease, 32);

            if (imgMain.Width > scroller.ActualWidth)
            {
                scroller.ScrollToHorizontalOffset(Math.Max(0D, scroller.HorizontalOffset - (xIncrease / 2D)));
            }

            if (imgMain.Height > scroller.ActualHeight)
            {
                scroller.ScrollToVerticalOffset(Math.Max(0D, scroller.VerticalOffset - (yIncrease / 2D)));
            }
        }

        private void imgMain_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            //Console.WriteLine(e.NewSize.ToString());
        }

        internal void ClearAll()
        {
            if (_dt != null)
            {
                _dt.Stop();
                _dt = null;
            }
            commandBar.FileImageViewModel = null;
            commandBar = null;
            FullViewerWindow = null;
            imageInfo.ClearAll();
            imgMain.ImageSource = null;
        }

        private void commandBar_RequestDelete(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            // HEREHERE
            RequestDelete.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void commandBar_RequestResize(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            RequestResize.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void commandBar_RequestResizeDelete(object sender, ObjectEventArgsNonRef<FileImageViewModel, bool> e)
        {
            RequestResizeDelete.RaiseEvent(this, e.obj1, e.obj2);
        }

        private void commandBar_RequestRotate(object sender, ObjectEventArgsNonRef<RotationParams, bool> e)
        {
            RequestRotate.RaiseEvent(this, e.obj1, e.obj2);
        }
    }
}

//if (vm.ImageSourceCached != null)
//{
//    imgMain.FileImageViewModel = vm;
//}
//else if (FileImageViewModel != null && vm != null && FileImageViewModel == vm)
//{
//    LazyLoadingImageSource._lazyLoaderImageSource.CancelAll();
//    vm.LoadBitmap();
//    var fi = vm.FileImage as FileImage;
//    var src = fi.GetTransformedBitmap(Convert.ToInt32(Math.Floor(fi.ImageSourceWidth)), Convert.ToInt32(Math.Floor(fi.ImageSourceHeight)), true);
//    byte[] bytes = fi.ImageBytesCached;
//    ImageSource imgSource = src.CreateImageSourceFromBitmap(bytes);                        
//    imgMain.FileImageViewModel = FileImageViewModel;
//    fi.ImageSource = imgSource;

//    //SetOriginalBitmapViewModel();
//}